import { BNode } from '../type/BNode';
import { IEvent } from '../type/IEvent';
import { TaskState } from '../type/TaskState';

/**
 *  单选树,并行执行
 *  有一个成功,则其他节点都将取消执行
 */
export class OptionTree extends BNode implements IEvent {
    public children: IEvent[] = [];

    iTime: number = 0;

    addChild(...nodes: IEvent[]) {
        for (const n of nodes) {
            this.children.push(n);
        }
    }

    onUpdate(dt: number): void {
        if (this.task.getState() != TaskState.running) {
            return;
        }
        this.iTime += dt;
        for (let i = 0; i < this.children.length; i++) {
            const node = this.children[i];
            if (node.task.getState() === TaskState.pending) {
                node.task.running();
                node.onStart(this.blackBoard);
            }
            if (node.task.getState() === TaskState.running) {
                node.onUpdate(dt);
            }
            if (node.task.getState() === TaskState.done) {
                this.cancelOther(i);
                this.task.done();
                return;
            }
        }
    }

    // 取消其他节点
    cancelOther(index: number) {
        for (let i = 0; i < this.children.length; i++) {
            if (index == i) {
                continue;
            }
            const node = this.children[i];
            node.task.error();
            node.onCancel();
        }
    }

    getState(): TaskState {
        return this.task.getState();
    }

    onCancel(): void {}

    onReset(): void {
        this.children.forEach((value) => {
            value.task.reset();
            value.onReset();
        });
    }

    onEvent(event: string, data?: any): void {
        for (let i = 0; i < this.children.length; i++) {
            this.children[i].onEvent(event, data);
        }
    }
}
